package qualomelhor.server;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.expressme.openid.*;

import qualomelhor.database.Usuario;
import qualomelhor.database.ParametrosSistema.OrigemLogin;

@SuppressWarnings("serial")
public class LoginOpenIdRedirectServlet extends HttpServlet {

    static final long ONE_HOUR = 3600000L;
    static final long TWO_HOUR = ONE_HOUR * 2L;
    static final String ATTR_MAC = "openid_mac";
    static final String ATTR_ALIAS = "openid_alias";

    private static final Map<String, String> openIdProviders;
    static {
        openIdProviders = new HashMap<String, String>();
        openIdProviders.put("Google", "google.com/accounts/o8/id");
        openIdProviders.put("Yahoo", "yahoo.com");
        openIdProviders.put("MySpace", "myspace.com");
        openIdProviders.put("AOL", "aol.com");
        openIdProviders.put("MyOpenId.com", "myopenid.com");
    }

    private OpenIdManager manager;

    @Override
    public void init() throws ServletException {
        super.init();
        manager = new OpenIdManager();
        //manager.setRealm("http://localhost:8888");
        //manager.setReturnTo("http://localhost:8888/loginOpenRedirect");
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    	String op = request.getParameter("op");
    	String server = request.getServerName();
    	if (server.indexOf("localhost") == 0) {
    		server = "localhost:8888";
    	}
    	manager.setRealm("http://" + server);
        manager.setReturnTo("http://" + server + "/loginOpenRedirect");

        if (op == null) {
            // check nonce:
            //checkNonce(request.getParameter("openid.response_nonce"));
        	System.out.println("nonce = [" + request.getParameter("openid.response_nonce") + "]");

            // get authentication:
            byte[] mac_key = (byte[]) request.getSession().getAttribute(ATTR_MAC);
            String alias = (String) request.getSession().getAttribute(ATTR_ALIAS);
            Authentication authentication = manager.getAuthentication(request, mac_key, alias);
            String identity = authentication.getIdentity();
            //identity = identity.substring(identity.indexOf("id=") + 3);
            String email = authentication.getEmail();
            System.out.println("email = " + email);
            System.out.println("identity = [" + identity + "]");
            System.out.println("Gender = " + authentication.getGender());
			HttpSession session = request.getSession(true);
			String siteOrigem = (String)session.getAttribute("SITEORIGEM");
            System.out.println("siteOrigem = " + siteOrigem);
            // TODO: create user if not exist in database:

            DAO d = new DAO();
			Usuario u = d.getUsuarioFB(identity);
			if (u == null) {
				System.out.println("novo usuario openId sendo criado..");
				u = new Usuario(email, identity, OrigemLogin.getOrigemLoginPerName(siteOrigem.toLowerCase()).getSiteOrigem(), authentication.getIdentity(), "", authentication.getFullname(), "", "", authentication.getLanguage(), "", true, "", new Date());
			} else {
				System.out.println("atualizando usuario do open id..");
				u.setAccessToken(authentication.getIdentity());
				u.setOrigemLogin(OrigemLogin.getOrigemLoginPerName(siteOrigem.toLowerCase()).getSiteOrigem());
			}
			d.gravaNovoUsuario(u);

			@SuppressWarnings("unchecked")
			HashMap<String, Object> mapSession = (HashMap<String, Object>)session.getAttribute("SESSIONVAR"); 

			if (mapSession == null) {
				mapSession = new HashMap<String, Object>(0);
			}

			mapSession.put("USUARIOATUAL", u);
			session.setAttribute("SESSIONVAR", mapSession);
			session.setAttribute("USUARIOATUAL", u);
			System.out.println("SETOU O USUARIO ATUAL: " + u.getNomeUsuario() + ", Admin:" + u.getAdmin() + ", OrigemLogin:" + u.getOrigemLogin());

			//response.sendRedirect("/logado.jsp?nome=" + u.getNomeUsuario() + "&id=" + authentication.getIdentity() + "&openid=true");
			response.sendRedirect("/");

        } else if ("Google".equals(op)) {
            // redirect to Google sign on page:
            Endpoint endpoint = manager.lookupEndpoint("Google");
            Association association = manager.lookupAssociation(endpoint);
            request.getSession().setAttribute(ATTR_MAC, association.getRawMacKey());
            request.getSession().setAttribute(ATTR_ALIAS, endpoint.getAlias());
            request.getSession().setAttribute("SITEORIGEM", "Google");
            String url = manager.getAuthenticationUrl(endpoint, association);
            response.sendRedirect(url);
        } else {
        	System.out.println("Tentando logar com a conta: [" + op + "]");
			request.getSession().setAttribute("SITEORIGEM", op);
        	try {
	        	Endpoint endpoint = manager.lookupEndpoint(op);
	        	if (endpoint == null) {
	        		if ("AOL".equals(op)) {
	        			endpoint = new Endpoint("http://openid.aol.com/teste", "ax", 30000);
	        		}
	        	}
	        	System.out.println("endpoint = " + endpoint.getUrl());
	            Association association = manager.lookupAssociation(endpoint);
	            request.getSession().setAttribute(ATTR_MAC, association.getRawMacKey());
	            request.getSession().setAttribute(ATTR_ALIAS, endpoint.getAlias());
	            String url = manager.getAuthenticationUrl(endpoint, association);
	            response.sendRedirect(url);
        	} catch (org.expressme.openid.OpenIdException e) {
        		System.out.println("Bad parameter op=" + op);
        		e.printStackTrace();
        	}
        }
    }
}
